page.once() 的竞态条件
page.once() 的核心是 “ 只监听一次,一旦触发就自动移除 ”。这带来一个明显的竞态问题:
当一个操作(比如 page.click())会触发多个网络请求时,page.once() 只会捕获到第一个返回的响应,而不管这个响应是不是你真正想要的。
例如,你点击一个按钮,它可能会触发:
一个 `GET /api/ping` 请求,用于检查服务状态。
一个 `POST /api/data` 请求,用于提交数据。
一个 `GET /images/loading.gif` 请求,用于加载动画。
如果你使用 page.once('response', fn),它会捕获到这三个请求中最先返回的那个响应。如果 GET /images/loading.gif 请求最先完成,page.once() 就会立即触发并移除监听器。此时,你真正想要的 POST /api/data 响应即便稍后返回,也不会被监听到了。
解决方案
为了解决这个问题,你可以:
使用 `page.waitForResponse()` 替代 `page.once()`:等待所有符合条件的响应返回,而不是只返回第一个;
使用 `page.on('response', fn)` 监听所有响应:自身实现 数据返回和错误处理机制;
综上,page.once('response', fn) 适合 不关心具体是哪个响应,只要第一个响应出现就行,或者你确定要等待的那个响应一定是第一个返回的 的场景。










